package com.junpuxin.component;

import com.junpuxin.exception.*;
import com.junpuxin.result.Result;
import com.junpuxin.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author junpuxin
 */
@Slf4j
@RestControllerAdvice(basePackages = {"com.junpuxin"})
public class ExceptionAdvice {

    @ExceptionHandler(ServerErrorException.class)
    public Object handleServerErrorException(ServerErrorException e) {
        String errorMessage = e.getMessage();
        log.error("业务异常 - 服务器内部错误：{}", errorMessage);
        return new Result<>(ResultCode.SERVER_ERROR, errorMessage);
    }

    @ExceptionHandler(IllegalParamException.class)
    public Object handleIllegalParamException(IllegalParamException e) {
        String errorMessage = e.getMessage();
        log.error("业务异常 - 非法参数：{}", errorMessage);
        return new Result<>(ResultCode.ILLEGAL_PARAM, errorMessage);
    }

    @ExceptionHandler(RepeatRecordException.class)
    public Object handleRepeatRecordException(RepeatRecordException e) {
        String errorMessage = e.getMessage();
        log.error("业务异常 - 重复记录：{}", errorMessage);
        return new Result<>(ResultCode.REPEAT_RECORD, errorMessage);
    }

    @ExceptionHandler(TokenExpiredException.class)
    public Object handleTokenExpiredException(TokenExpiredException e) {
        String errorMessage = e.getMessage();
        log.error("业务异常 - Token已过期：{}", errorMessage);
        return new Result<>(ResultCode.TOKEN_EXPIRED, errorMessage);
    }

    @ExceptionHandler(TokenExpiredSoonException.class)
    public Object handleTokenExpiringSoonException(TokenExpiredSoonException e) {
        String newToken = e.getMessage();
        String userMessage = "Token即将过期，请更新令牌";
        log.error("业务异常 - Token即将过期，新Token：{}", newToken);
        return new Result<>(ResultCode.TOKEN_EXPIRING_SOON, userMessage, newToken);
    }

    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
    public Object handleValidationException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        FieldError firstError = bindingResult.getFieldErrors().get(0);
        String errorMessage = String.format(
                "%s对象的%s字段校验失败：%s",
                firstError.getObjectName(),
                firstError.getField(),
                firstError.getDefaultMessage()
        );
        log.error("参数校验异常：{}", errorMessage);
        return new Result<>(ResultCode.ILLEGAL_PARAM, errorMessage);
    }

    @ExceptionHandler(Exception.class)
    public Object handleUncaughtException(Exception e) {
        String errorMessage = e.getMessage();
        log.error("未捕获异常：{}", errorMessage, e);
        return new Result<>(ResultCode.SERVER_ERROR, errorMessage);
    }

}